#include <game/controls/Control.h>
#include <game/XMLProperties.h>
#include <Atom.h>

#include <Object2D.h>

#include <system/assert.h>

#include <logs/Log.h>
#include <Signals.h>
#include <boost/bind.hpp>

namespace {
const char* LOGGER = "Control";
} // anonymous namespace

ARELLO_GAME_NAMESPACE_DECL_START
namespace controls {

struct ControlPrivates
{
	void OnObject2DDestroying();

	Atom name;
	int modalLevel;
	bool enabled;
	liba::Object2D* object2d;
	game::Properties props;
	signals::connection object2dDestroyingConnection;
	bool isOrphaned;
	signals::signal<void ()> orphaned;
	signals::signal<void ()> destroying;
};

Control::Control(const Atom& name, liba::Object2D* object2d) 
	: privates(new ControlPrivates())
{
	LIBA_ASSERT(object2d);

	privates->name = name;
	privates->modalLevel = 0;
	privates->enabled = true;
	privates->object2d = object2d;
	if (object2d)
	{
		privates->isOrphaned = false;
		privates->object2dDestroyingConnection = object2d->Destroying().connect(
			boost::bind(&ControlPrivates::OnObject2DDestroying, privates.get()));
	}
	else
	{
		privates->isOrphaned = true;
	}
}

Control::~Control()
{
}

const Properties& Control::GetProperties() const
{
	return privates->props;
}

void Control::SetProperties(const Properties &prop)
{
	privates->props = prop;
}

const liba::Atom& Control::GetName() const
{
	return privates->name;
}

liba::Object2D* Control::GetObject2D() const
{
	return privates->object2d;
}

void Control::SetEnabled(bool value)
{
	privates->enabled = value;
}

bool Control::IsEnabled()
{
	return privates->enabled;
}

void Control::SetModalLevel(int value)
{
	privates->modalLevel = value;
}

int Control::GetModalLevel()
{
	return privates->modalLevel;
}

bool Control::IsOrphaned()
{
	return privates->isOrphaned;
}

liba::signals::signal<void ()>& Control::Orphaned()
{
	return privates->orphaned;
}

void ControlPrivates::OnObject2DDestroying()
{
	LOG_DEBUG(LOGGER, "Control at 0x%08X becomes orphaned", this);
	this->isOrphaned = true;
	this->orphaned();
}

} // namespace controls
ARELLO_GAME_NAMESPACE_DECL_END